﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Meraz.Core.Model;
using Meraz.Core.Data;
using Meraz.Core.Repositories;
using Ninject;

namespace Meraz.Core.Commands
{
    public interface ISavePostCommand {
        IIssueRepository IssueRepository { get; set; }
        ILinkRepository LinkRepository { get; set; }
        IPosterRepository PosterRepository { get; set; }
        bool Execute(Post entity, Post post); 
        bool Execute(Post entity); 
    }
    public class SavePostCommand : BaseCommand, ISavePostCommand
    {
        [Inject]
        public IIssueRepository IssueRepository { get; set; }
        [Inject]
        public ILinkRepository LinkRepository { get; set; }
        [Inject]
        public IPosterRepository PosterRepository { get; set; }
        
        public bool Execute(Post entity, Post post)
        {
            entity.BlogName = post.BlogName;
            entity.Pubdate = post.Pubdate;
            entity.Title = post.Title;
            if (post.HasPosters)
            {
                List<int> aliasIDs = post.Posters.Select(select1 => select1.ID).ToList();
                List<int> oldAliasIDs = entity.Posters.Where(where1 => !aliasIDs.Contains(where1.ID)).Select(select1 => select1.ID).ToList();
                foreach (int oldID in oldAliasIDs)
                {
                    Poster old = entity.Posters.SingleOrDefault(where1 => where1.ID == oldID);
                    if (old == null)
                        continue;
                    entity.Posters.Remove(old);
                    PosterRepository.Delete(old);
                }
            }
            else if (entity.HasPosters)
            {
                foreach (int oldID in entity.Posters.Select(sel1 => sel1.ID).ToList())
                {
                    Poster old = entity.Posters.SingleOrDefault(where1 => where1.ID == oldID);
                    entity.Posters.Remove(old);
                    PosterRepository.Delete(old);
                }
            }
            if (post.HasIssues)
            {
                List<int> issueIDs = post.Issues.Select(select1 => select1.ID).ToList();
                List<int> oldIssueIDs = entity.Issues
                    .Where(where1 => !issueIDs.Contains(where1.ID))
                    .Select(select1 => select1.ID).ToList();
                foreach (int oldID in oldIssueIDs)
                {
                    Issue old = entity.Issues.SingleOrDefault(where1 => where1.ID == oldID);
                    if (old == null)
                        continue;
                    entity.Issues.Remove(old);
                    IssueRepository.Delete(old);
                }
                foreach (Issue issue in entity.Issues)
                {
                    issue.AffectiveFrameType = post.Issues.Where(where1 => where1.ID == issue.ID)
                        .Select(select1 => select1.AffectiveFrameType)
                        .FirstOrDefault();
                }
            }
            else if (entity.HasIssues)
            {
                foreach (int oldID in entity.Issues.Select(sel1 => sel1.ID).ToList())
                {
                    Issue old = entity.Issues.SingleOrDefault(where1 => where1.ID == oldID);
                    if (old == null)
                        continue;
                    entity.Issues.Remove(old);
                    IssueRepository.Delete(old);
                }
            }
            if (post.HasLinks)
            {
                List<int> linkIDs = post.Links.Select(select1 => select1.ID).ToList();
                List<int> oldLinkIDs = entity.Links
                    .Where(where1 => !linkIDs.Contains(where1.ID))
                    .Select(select1 => select1.ID).ToList();
                foreach (int oldID in oldLinkIDs)
                {
                    Link old = entity.Links.SingleOrDefault(where1 => where1.ID == oldID);
                    if (old == null)
                        continue;
                    entity.Links.Remove(old);
                    LinkRepository.Delete(old);
                }
                foreach (Link link in entity.Links)
                {
                    link.ToneType = post.Links.Where(where1 => where1.ID == link.ID)
                        .Select(select1 => select1.ToneType)
                        .FirstOrDefault();
                }
            }
            else if (entity.HasLinks)
            {
                foreach (int oldID in entity.Links.Select(sel1 => sel1.ID).ToList())
                {
                    Link old = entity.Links.SingleOrDefault(where1 => where1.ID == oldID);
                    if (old == null)
                        continue;
                    entity.Links.Remove(old);
                    LinkRepository.Delete(old);
                }
            }

            Commit();
            return true;
        }

        public bool Execute(Post entity)
        {
            Commit();
            return true;
        }
    }
}
